package sanrenxing.student.dao.impl;

import sanrenxing.Class.domain.ClassName;
import sanrenxing.student.dao.StudentDao;
import sanrenxing.student.domain.Student;
import sanrenxing.student.domain.StudentDo;
import sanrenxing.student.domain.StudentTo;
import sanrenxing.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 功能：
 * 编写者：阳赛
 * 日期：
 * 版本：1.0
 */
public class StudentDaoImpl implements StudentDao {

    /**
     * 将学生实体对象添加到studen表中
     * @param student 学生对象
     * @return 成功添加的行数(1 : 添加成功 ; 0 : 添加失败)
     */
    @Override
    public int add(Student student) {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //定义影响行数的变量
        int rows=0;
        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句字符串
            String sql="insert into student values(?,?,?,?,?,?,?,?)";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //设置SQl语句的占位符赋值
            pstmt.setString(1,student.getStuId());
            pstmt.setString(2,student.getStuName());
            pstmt.setString(3,student.getStuSex());
            pstmt.setInt(4,student.getClassId());
            pstmt.setString(5,student.getSelfId());
            pstmt.setString(6,student.getStuPwd());
            pstmt.setString(7,student.getStuPhone());
            pstmt.setString(8,student.getStuItb());
            //使用预编译语句对象执行SQL语句，返回影响的行数
            rows=pstmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        }finally {
        //关闭/释放资源
        JdbcUtils.close(null,pstmt,conn);
        }
        //返回影响的行数
        return rows;
    }

    /**
     * 根据学生编号主键从数据库student表中删除指定员工数据
     *
     * @param stuId 学生编号主键
     * @return 删除影响的行数（1：删除成功；0：删除失败）
     */
    @Override
    public int delete(String stuId) {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //定义影响的行数
        int rows=0;
        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写SQl语句字符串
            String sql="delete from student where stuId=?";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //设置SQL占位符赋值
            pstmt.setString(1,stuId);
            //使用预编译语句对象执行SQL语句，返回影响的行数
            rows=pstmt.executeUpdate();
        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
    } finally {
            //关闭/释放资源
            JdbcUtils.close(null,pstmt,conn);
        }
        //返回影响的行数
        return rows;
        }

    /**
     * 将学生对象数据修改到数据库Student表中
     * @param studentDo 学生对象
     * @return 修改影响的行数
     */
    @Override
    public int update(StudentDo studentDo) {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //定义影响的行数
        int rows=0;
        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句
            String sql="update student set stuName=?,stuSex=?,classId=(SELECT classId FROM class WHERE className=?),selfId=?,stuPwd=?,stuPhone=?,stuItb=? where  stuId=?";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //设置SQL语句中的占位符赋值
            pstmt.setString(1,studentDo.getStuName());
            pstmt.setString(2,studentDo.getStuSex());
            pstmt.setString(3,studentDo.getClassName());
            pstmt.setString(4,studentDo.getSelfId());
            pstmt.setString(5,studentDo.getStuPwd());
            pstmt.setString(6,studentDo.getStuPhone());
            pstmt.setString(7,studentDo.getStuItb());
            pstmt.setString(8,studentDo.getStuId());
            //使用预编译语句对象执行SQL语句，返回影响的行数
            rows=pstmt.executeUpdate();
        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        } finally {
            //关闭/释放资源
            JdbcUtils.close(null,pstmt,conn);
        }
        //返回影响的行数
        return rows;
    }

    /**
     * 根据学生编号主键从数据库student表中查找单个学生
     * @param stuId 学生编号主键
     * @return 学生对象(如果返回null值 ， 表示查找失败)
     */
    @Override
    public Student findById(String stuId) {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //声明结果集对象
        ResultSet rs=null;
        //定义返回的学生对象
        Student student=null;
        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句字符串
            String sql="select stuId,stuName,stuSex,classId,selfId," +
                    "stuPwd,stuPhone,stuItb from student where stuId=?";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //设置SQL语句中占位符赋值
            pstmt.setString(1,stuId);
            //使用预编译语句对象执行SQL语句，返回结果集
            rs=pstmt.executeQuery();
            //判断结果集，并把结果集的数据封装到学生对象中
            if(rs.next()){
                //实例化学生对象
                student=new Student();
                //把结果集数据赋值给学生对象各属性
                student.setStuId(rs.getString("stuId"));
                student.setStuName(rs.getString("stuName"));
                student.setStuSex(rs.getString("stuSex"));
                student.setClassId(rs.getInt("classId"));
                student.setSelfId(rs.getString("selfId"));
                student.setStuPwd(rs.getString("stuPwd"));
                student.setStuPhone(rs.getString("stuPhone"));
                student.setStuItb(rs.getString("stuItb"));

            }
        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        } finally {
            //关闭/释放资源
            JdbcUtils.close(rs,pstmt,conn);
        }
        //返回学生对象
        return student;
    }

    /**
     * 查询数据库student表中所有学生
     *
     * @return 学生对象集合
     */
    @Override
    public List<Student> findAll() {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //声明结果集对象
        ResultSet rs=null;
        //定义返回的学生对象集合
        List<Student> studentList=new ArrayList<Student>();
        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句字符串
            String sql="select stuId,stuName,stuSex,classId,selfId," +
                    "stuPwd,stuPhone,stuItb from student";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //使用预编译语句对象执行SQL语句，返回结果集
            rs=pstmt.executeQuery();
            //循环判断结果集，并把结果集的数据封装到员工对象中+
            while(rs.next()){
                //定义学生对象
                Student student=new Student();
                //把结果集数据赋值给学生对象各属性
                student.setStuId(rs.getString("stuId"));
                student.setStuName(rs.getString("stuName"));
                student.setStuSex(rs.getString("stuSex"));
                student.setClassId(rs.getInt("classId"));
                student.setSelfId(rs.getString("selfId"));
                student.setStuPwd(rs.getString("stuPwd"));
                student.setStuPhone(rs.getString("stuPhone"));
                student.setStuItb(rs.getString("stuItb"));
                //把学生对象添加员工集合中
                studentList.add(student);
            }
        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        } finally {
            //关闭/释放资源
            JdbcUtils.close(rs,pstmt,conn);
        }
        //返回学生对象集合
        return studentList;
    }

    /**
     * 查询数据库student表中所有学生
     *
     * @return 学生对象集合
     */
    @Override
    public List<Student> findByPage(int rows, int pages) {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //声明结果集对象
        ResultSet rs=null;
        //定义返回的学生对象集合
        List<Student> studentList=new ArrayList<Student>();
        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句字符串
            String sql="select stuId,stuName,stuSex,classId,selfId," +
                    "stuPwd,stuPhone,stuItb from student";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //使用预编译语句对象执行SQL语句，返回结果集
            rs=pstmt.executeQuery();
            //循环判断结果集，并把结果集的数据封装到员工对象中
            while(rs.next()){
                //定义学生对象
                Student student=new Student();
                //把结果集数据赋值给学生对象各属性
                student.setStuId(rs.getString("stuId"));
                student.setStuName(rs.getString("stuName"));
                student.setStuSex(rs.getString("stuSex"));
                student.setClassId(rs.getInt("classId"));
                student.setSelfId(rs.getString("selfId"));
                student.setStuPwd(rs.getString("stuPwd"));
                student.setStuPhone(rs.getString("stuPhone"));
                student.setStuItb(rs.getString("stuItb"));
                //把学生对象添加员工集合中
                studentList.add(student);
            }
        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        } finally {
            //关闭/释放资源
            JdbcUtils.close(rs,pstmt,conn);
        }
        //返回员工对象集合
        return studentList;
    }

    /**
     * 统计数据库student表中记录总数
     *
     * @return student表中记录总数
     */
    @Override
    public int count() {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //声明结果集对象
        ResultSet rs=null;
        //定义返回表中总数据行数
        int rowCount=0;
        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句字符串
            String sql="select count(*) as studentcount from student";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //使用预编译语句对象执行SQL语句，返回结果集合
            rs=pstmt.executeQuery();
            //判断结果集，并获得总行数
            if(rs.next()){
                //如果统计行数时没有指定别名，则用数字0作为参数
                rowCount=rs.getInt("studentcount");
            }
        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        } finally {
            //关闭/释放资源
            JdbcUtils.close(null,pstmt,conn);
        }
        //返回表中数据总行数
        return rowCount;
    }

    /**
     * 条件分页查询
     *
     * @param rows      每页行数
     * @param pages     页数
     * @param condition 条件
     * @return 学生对象集合
     */
    @Override
    public List<StudentTo> findByPage(int rows, int pages, String condition) {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //声明结果集对象
        ResultSet rs=null;
        //定义返回的学生对象集合
        List<StudentTo> studenttToList=new ArrayList<StudentTo>();
        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句字符串
            String sql="SELECT stu.stuId,stu.stuName,stu.stuSex,cl.className,stu.selfId,stu.stuPwd,stu.stuPhone,stu.stuItb FROM student stu JOIN class cl ON stu.classId=cl.classId WHERE 1=1 "+condition+" LIMIT ?,?";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //给分页语句占位符赋值
            //分页语句：select * from 表名 limits (pages-1)*rows,rows
            pstmt.setInt(1,(pages-1)*rows);
            pstmt.setInt(2,rows);
            //使用预编译语句对象执行SQL语句，返回结果集
            rs=pstmt.executeQuery();
            //循环判断结果集，并把结果集的数据封装到学生对象中
            while(rs.next()){
                //定义学生对象
                StudentTo studentTo=new StudentTo();
                //把结果集数据赋值给学生对象各属性
                studentTo.setStuId(rs.getString("stuId"));
                studentTo.setStuName(rs.getString("stuName"));
                studentTo.setStuSex(rs.getString("stuSex"));
                studentTo.setClassName(rs.getString("className"));
                studentTo.setSelfId(rs.getString("selfId"));
                studentTo.setStuPwd(rs.getString("stuPwd"));
                studentTo.setStuPhone(rs.getString("stuPhone"));
                studentTo.setStuItb(rs.getString("stuItb"));
                //把学生对象添加学生集合中
                studenttToList.add(studentTo);
            }
        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        } finally {
            //关闭/释放资源
            JdbcUtils.close(rs,pstmt,conn);
        }
        //返回员工对象集合
        return studenttToList;
    }

    /**
     * 条件统计
     *
     * @param condition 条件
     * @return 学生数
     */
    @Override
    public int count(String condition) {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //声明结果集对象
        ResultSet rs=null;
        //定义返回表中总数据行数
        int rowCount=0;
        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句字符串
            String sql="select count(*) as studentcount from student stu where 1=1 "+condition;
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //使用预编译语句对象执行SQL语句，返回结果集合
            rs=pstmt.executeQuery();
            //判断结果集，并获得总行数
            if(rs.next()){
                //如果统计行数时没有指定别名，则用数字0作为参数
                rowCount=rs.getInt("studentcount");
                rowCount=rs.getInt("studentcount");
            }
        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        } finally {
            //关闭/释放资源
            JdbcUtils.close(null,pstmt,conn);
        }
        //返回表中数据总行数
        return rowCount;
    }

    /**
     * 获取查询条件
     *
     * @param student 学生对象
     * @return 条件字符串
     */
    @Override
    public String getCondition(Student student) {//定义查询条件字符串，初值为带空格的字符串(注意后续条件中的空格)
        String condition=" ";
        //如果学生对象为空，则直接返回空字符串
        if(student==null){
            return condition;
        }
        //如果学生编号不为空(字符串匹配模糊查询)
        if(student.getStuId()!=null && student.getStuId().trim().length()!=0){
            condition += " and stu.stuId like '%"+student.getStuId()+"%' ";
        }
        //如果学生姓名不为空(字符串匹配模糊查询)
        if(student.getStuName()!=null && student.getStuName().trim().length()!=0){
            condition += " and stu.stuName like '%"+student.getStuName()+"%' ";
        }
        //如果学生性别不为空
        if(student.getStuSex()!=null && student.getStuSex().trim().length()!=0){
            condition += " and stu.stuSex like '%"+student.getStuSex()+"%' ";
        }
        //如果不存在班级编号
        if(student.getClassId()!=0){
            condition += " and stu.classId="+student.getClassId();
        }
        //如果身份证号码为空
        if(student.getSelfId()!=null && student.getSelfId().trim().length()!=0){
            condition += " and stu.selfId like '%"+student.getSelfId()+"%' ";
        }

        //如果学员密码不为空
        if(student.getStuPwd()!=null && student.getStuPwd().trim().length()!=0){
            condition += " and stu.stuPwd like '%"+student.getStuPwd()+"%' ";
        }
        //如果学员电话不为空
        if(student.getStuPhone()!=null && student.getStuPhone().trim().length()!=0){
            condition += " and stu.stuPhone like '%"+student.getStuPhone()+"%' ";
        }
        //如果学员不在籍
        if(student.getStuItb()!=null && student.getStuItb().trim().length()!=0){
            condition += " and stu.stuItb like '"+student.getStuItb()+"' ";
        }


        //返回条件字符串
        return condition;
    }

    @Override
    public int findClassName(String className) {
        int classId;
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //声明结果集对象
        ResultSet rs=null;
        //定义返回的班级名称对象集合
        List<ClassName> classNameList=new ArrayList<>();


        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句字符串
            String sql="SELECT  classId FROM class where className=? ";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //给班级名称赋值
            pstmt.setString(1,className);
            //使用预编译语句对象执行SQL语句，返回结果集合
            rs=pstmt.executeQuery();
            //判断结果集，并获得班级编号
            if (rs.next()){

                classId=rs.getInt("classId");
                //设置班级编号为返回值
                return classId;
            }

        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        }finally {
            //关闭/释放资源
            JdbcUtils.close(rs,pstmt,conn);
        }
        //如果为空，则返回值为0
        return 0;
    }

    /**
     * 通过班级名称查询班级人数且每运行一次添加1个人数
     *
     * @param className
     * @return
     */
    @Override
    public int addClassCount(String className) {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //定义影响的行数
        int rows=0;

        try {
            //实列化连接对象
            conn= JdbcUtils.getConnection();
            //编写sql语句字符串
            String sql="UPDATE class SET studentCount=(studentCount+1) WHERE className=?";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //设置SQL语句中的占位符赋值
            pstmt.setString(1,className);
            //使用预编译语句对象执行SQL语句，返回影响的行数
            rows=pstmt.executeUpdate();
        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage() ,e);
        }finally {
            //关闭/释放资源
            JdbcUtils.close(null,pstmt,conn);
        }
        //设置返回值为影响的行数
        return rows;
    }

    /**
     * 通过班级编号查询班级名称
     *
     * @param classId
     * @return
     */
    @Override
    public String findClassId(int classId) {
        //定义班级名称为字符串
        String className;
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //声明结果集对象
        ResultSet rs=null;
        //定义返回的班级名称对象集合
        List<ClassName> classNameList=new ArrayList<>();


        try {
            //实列化连接对象
            conn= JdbcUtils.getConnection();
            //编写sql语句字符串
            String sql="SELECT  className FROM class where classId=? ";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //为SQL语句中的占位符赋值
            pstmt.setInt(1,classId);
            //使用预编译语句对象执行SQL语句，返回结果集合
            rs=pstmt.executeQuery();
            //判断结果集，并获得班级名称
            if (rs.next()){
                //为班级名称赋值
                className=rs.getString("className");
                //设置返回值为班级名称
                return className;
            }

        } catch (SQLException e) {
            throw new RuntimeException(e.getMessage(),e);
        }finally {
            //关闭/释放资源
            JdbcUtils.close(rs,pstmt,conn);
        }
        //设置返回值为空
        return null;
    }

    /**
     * 通过学员编号查询班级编号
     *
     * @param stuId
     * @return
     */
    @Override
    public int findclassId(String stuId) {
        //设置班级编号为整形
        int classId;
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //声明结果集对象
        ResultSet rs=null;
        try {
            //实列化连接对象
            conn= JdbcUtils.getConnection();
            //编写sql语句字符串
            String sql="SELECT  classId FROM student where stuId=? ";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //为SQL语句中的占位符赋值
            pstmt.setString(1,stuId);
            //使用预编译语句对象执行SQL语句，返回结果集合
            rs=pstmt.executeQuery();
            //判断结果集，并获得班级编号
            if (rs.next()){
                //为编辑编号赋值
                classId=rs.getInt("classId");
                //返回值为班级编号
                return classId;
            }

        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        }finally {
            //关闭/释放资源
            JdbcUtils.close(rs,pstmt,conn);
        }
        //定义返回值为0
        return 0;
    }

    /**
     * 通过班级名称查询班级人数且每运行一次删除1个人数
     *
     * @param className
     * @return
     */
    @Override
    public int deleteClassCount(String className) {

        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //定义影响的行数
        int rows=0;

        try {
            //实列化连接对象
            conn= JdbcUtils.getConnection();
            //编写sql语句字符串
            String sql="UPDATE class SET studentCount=(studentCount-1) WHERE className=?";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //设置SQL语句中的占位符赋值
            pstmt.setString(1,className);
            //使用预编译语句对象执行SQL语句，返回影响的行数
            rows=pstmt.executeUpdate();
        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage() ,e);
        }finally {
            //关闭/释放资源
            JdbcUtils.close(null,pstmt,conn);
        }
        //返回影响的行数
        return rows;
    }

    /**
     * 通过学员编号修改对应班级人数
     *
     * @param classId
     */
    @Override
    public void updateClassCount(int classId) {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;

        try {
            //实列化连接对象
            conn= JdbcUtils.getConnection();
            //编写sql语句字符串
            String sql="UPDATE class SET studentCount=(SELECT COUNT(*) FROM student WHERE classId=?)" +
                    " WHERE classId=?";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //设置SQL语句中的占位符赋值
            pstmt.setInt(1,classId);
            pstmt.setInt(2,classId);
            //使用预编译语句对象执行SQL语句
            pstmt.executeUpdate();
        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage() ,e);
        }finally {
            //关闭/释放资源
            JdbcUtils.close(null,pstmt,conn);
        }
    }

}